﻿using System;
using System.Data;

namespace LaoLuo.Data.LayeredFramework
{
    /// <summary>
    /// base of business logic layer
    /// </summary>
    /// <typeparam name="TTransaction"></typeparam>
    public abstract class BusinessLogicLayerBase<TTransaction> : ITransactionControllerContainer<TTransaction>, ITransactionController
        where TTransaction : TransactionController, new ()
        //where TDataAccessLayer : DataAccessLayerBase<TTransaction>
    {
        //protected TDataAccessLayer _dataAccessLayer;

        /// <summary>
        /// 
        /// </summary>
        public TTransaction TransactionController { get; private set; }

        public int TransactionDepth
        {
            get { return TransactionController.TransactionDepth; }
        }

        public bool IsBegin
        {
            get { return TransactionController.IsBegin; }
        }

        public bool IsCommit
        {
            get { return TransactionController.IsCommit; }
        }

        public bool IsRollBack
        {
            get { return TransactionController.IsRollBack; }
        }

        public bool IsReal
        {
            get { return TransactionController.IsReal; }
        }

        /// <summary>
        /// if there is no current transaction, make one. else increace <see cref="TransactionDepth"/>
        /// </summary>
        public void BeginTransaction(IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
        {
            if (TransactionController == null)
            {
                TransactionController = new TTransaction();
            }

            TransactionController.BeginTransaction(isolationLevel);
        }

        /// <summary>
        /// commit current transaction if it is a real one
        /// </summary>
        public void CommitTransaction()
        {
            if (TransactionController == null)
                throw new ApplicationException("transaction not found");
            TransactionController.CommitTransaction();
        }

        /// <summary>
        /// rollback if current transaction is a real one. else decrease <see cref="TransactionDepth"/>
        /// </summary>
        public void RollbackTransaction()
        {
            if (TransactionController == null)
                throw new ApplicationException("transaction not found");
            TransactionController.RollbackTransaction();
        }

        /// <summary>
        /// rollback current transaction
        /// </summary>
        public void RealRollbackTransaction()
        {
            if (TransactionController == null)
                throw new ApplicationException("transaction not found");
            TransactionController.RealRollbackTransaction();
        }

        /// <summary>
        /// 引用一个事务控制器,用此方法构建事务链
        /// </summary>
        /// <param name="transactionController"></param>
        public virtual void ReferenceTransactionControllerFrom(TTransaction transactionController)
        {
            TransactionController = transactionController;
        }

        /// <summary>
        /// 引用一个事务控制器,用此方法构建事务链
        /// </summary>
        /// <param name="transactionControllerContainer"></param>
        public void ReferenceTransactionControllerFrom(ITransactionControllerContainer<TTransaction> transactionControllerContainer)
        {
            ReferenceTransactionControllerFrom(transactionControllerContainer.TransactionController);
        }

        /// <summary>
        /// 传递一个事务控制器,用此方法构建事务链
        /// </summary>
        /// <param name="transactionControllerContainer"></param>
        public void PassTransactionControllerTo(params ITransactionControllerContainer<TTransaction>[] transactionControllerContainer)
        {
            foreach (var businessLogicLayer in transactionControllerContainer)
            {
                businessLogicLayer.ReferenceTransactionControllerFrom(this);
            }
        }
    }
}
